package gupao.concurrency.datasync.task.v1x;

import gupao.concurrency.utils.FutureUtil;
import gupao.concurrency.utils.ThreadPoolService;
import gupao.concurrency.utils.Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@Component
public class WordProviderMockOpt1 {

    protected final ThreadPoolExecutor executor = ThreadPoolService.getOrCreate
            ("word-provider", 2, 100, new SynchronousQueue<>()
                    , new ThreadPoolExecutor.CallerRunsPolicy());

    public Collection<List<String>> queryAllWord(int partitionNum, int totalNum) {
        log.info("prepare words...");
        long start = System.currentTimeMillis();
        int x = totalNum / partitionNum;
        int y = totalNum % partitionNum;
//        List<List<String>> lists = new ArrayList<>();
        ConcurrentSkipListSet<List<String>> lists =
                new ConcurrentSkipListSet<>(Comparator.comparingInt(List::hashCode));
        List<Future<?>> fsList = new ArrayList<>();
        for (int i = 0; i < partitionNum; i++) {
            Future<?> fs = executor.submit(() -> {
                List<String> list = new ArrayList<>();
                for (int k = 0; k < x; k++) {
                    list.add(UUID.randomUUID().toString());
                    Utils.sleepIgnoreExp(1);
                }
                lists.add(list);
            });
            fsList.add(fs);
        }
        FutureUtil.waitFuturesComplete(fsList);
        if (y > 0) {
            Iterator<List<String>> it = lists.iterator();
            while (it.hasNext() && y > 0) {
                it.next().add(UUID.randomUUID().toString());
                y--;
            }
        }
        log.info("provide word list {} time cost: {}ms", totalNum, (System.currentTimeMillis() - start));
        return lists;
    }
}
